package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.mingqijia.gassafety.db.entity.Contacts;
import com.mingqijia.gassafety.db.entity.DeviceState;
import com.mingqijia.gassafety.db.entity.ValveInfo;
import com.mingqijia.gassafety.shared.constant.PageListCode;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.webserver.response.FieldListShowResponse;
import com.mingqijia.gassafety.webserver.response.WarningDataResponse;
import com.mingqijia.gassafety.webserver.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName CommonServiceImpl.java
 * @Description TODO
 * @createTime 2023年09月26日
 */
@Slf4j
@Service
public class CommonServiceImpl implements CommonService {

    @Autowired
    private ContactsService contactsService;

    @Autowired
    private ValveInfoService valveInfoService;

    @Autowired
    private DeviceStateService deviceStateService;

    @Autowired
    private FieldListShowService fieldListShowService;

    /**
     * 动态列表和导出提供联系人信息查询
     *
     * @param consumerIds
     * @return
     */
    public Map<Integer, List<Contacts>> getContacts(List<Integer> consumerIds, String spId) {
        log.info("getContacts-params:{},{}", JSON.toJSONString(consumerIds),spId);
        return contactsService.getContacts(consumerIds, spId);
    }

    /**
     * 动态列表和导出提供电磁阀信息查询
     *
     * @param valveInfoIds
     * @return
     */
    public Map<Integer, ValveInfo> getValveInfo(List<Integer> valveInfoIds, String spId) {
        log.info("getValveInfo-params:{},{}", JSON.toJSONString(valveInfoIds),spId);
        return valveInfoService.getValveInfo(valveInfoIds, spId);
    }


    /**
     * 动态列表和导出提供设备状态等最新上报信息
     *
     * @param deviceIds
     * @return
     */
    public Map<String, DeviceState> getDeviceState(List<String> deviceIds, String spId) {
        log.info("getDeviceState-params:{},{}", JSON.toJSONString(deviceIds),spId);
        return deviceStateService.getDeviceState(deviceIds, spId);
    }


    /**
     * 动态列表数据是否加载
     *
     * @param listCode
     * @return
     */
    public List<Integer> loadField(String listCode, String spId) {
        return fieldListShowService.loadField(listCode, spId);
    }


    /**
     * 动态列表并组装数据
     *
     * @return
     */
    public <T> List<T> loadFieldAndPackaging(Object response, Class<T> clazz, List<Integer> consumerIds,
                                             List<Integer> valveInfoIds, List<String> iMEIs, String spId,String code) {
        log.info("loadFieldAndPackaging-params:{},{},{}",JSON.toJSON(consumerIds),JSON.toJSON(valveInfoIds),JSON.toJSON(iMEIs));
        List<Object> loadBean = (List<Object>) response;
        try {
        List<Integer> loadField = loadField(code, ApplicationUtils.getWorkingUser().getUsername());
        log.info("loadFieldAndPackaging-loadField:{}",JSON.toJSON(loadField));
            if (loadField.contains(1) && !CollectionUtils.isEmpty(consumerIds)) {
                Map<Integer, List<Contacts>> contacts = this.getContacts(consumerIds, spId);
                log.info("loadFieldAndPackaging-contacts:{}", JSON.toJSONString(contacts));
                loadBean.forEach(o -> {
                    log.info("loadFieldAndPackaging-o1:{}", JSON.toJSONString(o));
                    try {
                        Field consumerId = clazz.getDeclaredField("consumerId");
                        consumerId.setAccessible(true);
                        List<Contacts> contact = contacts.get(consumerId.get(o));
                        log.info("loadFieldAndPackaging-contact:{}", JSON.toJSONString(contact));
                        Object c = dealContacts(contact);
                        log.info("loadFieldAndPackaging-c:{}", JSON.toJSONString(c));
                        Method setContact = clazz.getMethod("setContact", Object.class);
                        setContact.invoke(o,c);
                        log.info("loadFieldAndPackaging-o2:{}",JSON.toJSON(o));
                    } catch (Exception e) {
                        log.error("consumer-error:{}",e);
                    }
                });
                log.info("loadFieldAndPackaging-loadBean:{}",JSON.toJSON(loadBean));
            }
            if (loadField.contains(2) && !CollectionUtils.isEmpty(valveInfoIds)) {
                Map<Integer, ValveInfo> valveInfo = this.getValveInfo(valveInfoIds, spId);
                log.info("loadFieldAndPackaging-valveInfo:{}", JSON.toJSONString(valveInfo));
                loadBean.forEach(o -> {
                    try {
                        Field valveInfoId = clazz.getDeclaredField("valveInfoId");
                        valveInfoId.setAccessible(true);
                        ValveInfo valve = valveInfo.get(valveInfoId.get(o));
                        log.info("loadFieldAndPackaging-valve:{}", JSON.toJSONString(valve));
                        if (valve != null) {
                            Field valveName = clazz.getDeclaredField("valveName");
                            valveName.setAccessible(true);
                            valveName.set(o, valve.getValveName());
                            Field valveModel = clazz.getDeclaredField("valveModel");
                            valveModel.setAccessible(true);
                            valveModel.set(o, valve.getValveModel());
                            Field valveMaterial = clazz.getDeclaredField("valveMaterial");
                            valveMaterial.setAccessible(true);
                            valveMaterial.set(o, valve.getValveMaterial());
                            Field valveManufacturer = clazz.getDeclaredField("valveManufacturer");
                            valveManufacturer.setAccessible(true);
                            valveManufacturer.set(o, valve.getValveManufacturer());
                        }
                    } catch (Exception e) {
                        log.error("valveInfo-error:{}",e);
                    }
                });
                log.info("loadFieldAndPackaging-loadBean:{}",JSON.toJSON(loadBean));
            }
            if (loadField.contains(3) && !CollectionUtils.isEmpty(iMEIs)) {
                Map<String, DeviceState> deviceState = this.getDeviceState(iMEIs, spId);
                log.info("loadFieldAndPackaging-deviceState:{}", JSON.toJSONString(deviceState));
                loadBean.forEach(o -> {
                    try {
                        Field imei = clazz.getDeclaredField("iMEI");
                        imei.setAccessible(true);
                        DeviceState state = deviceState.get(imei.get(o));
                        if (state != null) {
                            Field equipmentStatus = clazz.getDeclaredField("equipmentStatus");
                            equipmentStatus.setAccessible(true);
                            equipmentStatus.set(o, state.getDeviceStatusInfo());
                            Field latestTime = clazz.getDeclaredField("latestTime");
                            latestTime.setAccessible(true);
                            latestTime.set(o, DateUtil.format(state.getUpdatedAt(), "yyyy-MM-dd HH:mm:ss"));
                        }
                    } catch (Exception e) {
                        log.error("imei-error:{}",e);
                    }
                });
                log.info("loadFieldAndPackaging-loadBean:{}",JSON.toJSON(loadBean));
            }
        } catch (Exception e) {
            log.error("loadFieldAndPackaging-error:{}",e);
        }

        return (List<T>) loadBean;
    }

    public Object dealContacts(List<Contacts> contacts) {
        log.info("dealContacts-contacts:{}",JSON.toJSON(contacts));
        String[] result = new String[30];
        if (CollectionUtils.isEmpty(contacts)) return result;
        Map<Integer, List<Contacts>> collect = contacts.stream().collect(Collectors.groupingBy(Contacts::getLevel));
        int j = 0;
        for (int i = -1; i < 20; i = i + 2) {
            List<Contacts> con =new ArrayList<>();
             con = collect.get(j + 1);
            if (CollectionUtils.isEmpty(con)) {
                result[i + 1] = "";
                result[i + 2] = "";
            } else {
                Contacts contacts1 = con.get(0);
                result[i + 1] = contacts1.getName();
                result[i + 2] = contacts1.getTelephone();
            }
            j++;
        }
//        j = 0;
//        for (int i = 20; i < 30; i++) {
//            List<Contacts> con = collect.get(j + 1);
//            if (CollectionUtils.isEmpty(con)) {
//                result[i] ="";
//            }else {
//                Contacts contacts1 = con.get(0);
//                result[i] = contacts1.getLevel()+"";
//            }
//            j++;
//        }
        log.info("dealContacts-result:{}",JSON.toJSON(result));
        return (Object) result;
    }
}